home *** CD-ROM | disk | FTP | other *** search
- /*
- Commodore 64 Emulator v0.4 Earle F. Philhower III
- Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include "Processor.h"
- #include "Instructions.h"
- #include "Stack.h"
- #include "Modes.h"
- #include "Error.h"
-
- /* Rather than using multiplication and division to do the BCD math, it's implemented
- * with lookup tables--faster and easier to code in 68K assembly.
- */
- unsigned char bcd2dec[256] =
- {
- /* 0x00 */ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
- /* 0x10 */ 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
- /* 0x20 */ 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,
- /* 0x30 */ 30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,
- /* 0x40 */ 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,
- /* 0x50 */ 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,
- /* 0x60 */ 60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,
- /* 0x70 */ 70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,
- /* 0x80 */ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
- /* 0x90 */ 90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,
- /* 0xA0 */ 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
- /* 0xB0 */ 110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
- /* 0xC0 */ 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
- /* 0xD0 */ 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
- /* 0xE0 */ 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,
- /* 0xF0 */ 150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165
- };
-
- unsigned char dec2bcd[100] =
- {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
- 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
- 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
- 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
- 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
- 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
- 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
- 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99
- };
-
- void i00() {
- PushWord(pc);
- flags |= BKC;
- Push(flags);
- flags &= ~BKC;
- pc=WordAt(IrqTo); }
- void i01() { ORA(IndirectXAddr); pc++; }
- void i05() { ORA(ZeroPageAddr); pc++; }
- void i06() { ASL(ZeroPageAddr); pc++; }
- void i08() { Push(flags); }
- void i09() { a |= ImmediateByte(); FlagsNZ(a); pc++; }
- void i0a() {
- if (a&128) flags |= CAR;
- else flags &= ~CAR;
- a=a<<1;
- FlagsNZ(a); }
- void i0d() { ORA(AbsoluteAddr); pc+=2; }
- void i0e() { ASL(AbsoluteAddr); pc+=2; }
- void i10() { BCL(NEG); }
- void i11() { ORA(IndirectYAddr); pc++; }
- void i15() { ORA(ZeroPageXAddr); pc++; }
- void i16() { ASL(ZeroPageXAddr); pc++; }
- void i18() { CLR(CAR); }
- void i19() { ORA(AbsoluteYAddr); pc+=2; }
- void i1d() { ORA(AbsoluteXAddr); pc+=2; }
- void i1e() { ASL(AbsoluteXAddr); pc+=2; }
- void i20() { PushWord(pc+1); pc=WordAt(pc); }
- void i21() { AND(IndirectXAddr); pc++; }
- void i24() { BIT(ZeroPageAddr); pc++; }
- void i25() { AND(ZeroPageAddr); pc++; }
- void i26() { ROL(ZeroPageAddr); pc++; }
- void i28() { flags = Pop(); }
- void i29() { a &= ImmediateByte(); FlagsNZ(a); pc++; }
- void i2a() {
- if (flags&CAR) {
- if ((a&128)==0) flags &=~CAR;
- a=(a<<1)|1; }
- else {
- if(a&128)flags|=CAR;
- a=a<<1; }
- FlagsNZ(a);
- }
- void i2c() { BIT(AbsoluteAddr); pc+=2; }
- void i2d() { AND(AbsoluteAddr); pc+=2; }
- void i2e() { ROL(AbsoluteAddr); pc+=2; }
- void i30() { BST(NEG); }
- void i31() { AND(IndirectYAddr); pc++; }
- void i35() { AND(ZeroPageXAddr); pc++; }
- void i36() { ROL(ZeroPageXAddr); pc++; }
- void i38() { SET(CAR); }
- void i39() { AND(AbsoluteYAddr); pc+=2; }
- void i3d() { AND(AbsoluteXAddr); pc+=2; }
- void i3e() { ROL(AbsoluteXAddr); pc+=2; }
- void i40() { flags=Pop(); PopWord(pc); }
- void i41() { EOR(IndirectXAddr); pc++; }
- void i45() { EOR(ZeroPageAddr); pc++; }
- void i46() { LSR(ZeroPageAddr); pc++; }
- void i48() { Push(a); }
- void i49() { a ^= ImmediateByte(); FlagsNZ(a); pc++; }
- void i4a() {
- flags &=~(CAR+NEG+ZER);
- if (a&1) flags |=CAR;
- if (a=a>>1); else flags |=ZER;
- }
- void i4c() { pc=WordAt(pc); }
- void i4d() { EOR(AbsoluteAddr); pc+=2; }
- void i4e() { LSR(AbsoluteAddr); pc+=2; }
- void i50() { BCL(OVF); }
- void i51() { EOR(IndirectYAddr); pc++; }
- void i55() { EOR(ZeroPageXAddr); pc++; }
- void i56() { LSR(ZeroPageXAddr); pc++; }
- void i58() { CLR(INT); }
- void i59() { EOR(AbsoluteYAddr); pc+=2; }
- void i5d() { EOR(AbsoluteXAddr); pc+=2; }
- void i5e() { LSR(AbsoluteXAddr); pc+=2; }
- void i60() { PopWord(pc); pc++; }
- void i61() { ADC(IndirectXAddr); pc++; }
- void i65() { ADC(ZeroPageAddr); pc++; }
- void i66() { ROR(ZeroPageAddr); pc++; }
- void i68() { a=Pop(); FlagsNZ(a); }
- void i69() {
- register word data;
- data=ImmediateByte();
- if (flags&DEC) {
- data = bcd2dec[data]+bcd2dec[a]+((flags&CAR)?1:0);
- flags &= ~(CAR+OVF+NEG+ZER);
- if (data>99) {
- flags|=CAR+OVF;
- data -=100; }
- if (data==0) flags |= ZER;
- else flags |= data&128;
- a=dec2bcd[data];}
- else {
- data += a+((flags&CAR)?1:0);
- flags &= ~(CAR+OVF+NEG+ZER);
- if (data>255) {
- flags|=OVF+CAR;
- data &=255; }
- if (data==0) flags |= ZER;
- else flags |= data&128;
- a=data; }
- pc++;
- }
- void i6a() {
- if (flags&CAR) {
- if ((a&1)==0) flags &=~CAR;
- a=(a>>1)|128; }
- else {
- if(a&1) flags|=CAR;
- a=a>>1; }
- FlagsNZ(a);
- }
- void i6c() { register word ta; ta=WordAt(pc); pc=WordAt(ta); }
- void i6d() { ADC(AbsoluteAddr); pc+=2; }
- void i6e() { ROR(AbsoluteAddr); pc+=2; }
- void i70() { BST(OVF); }
- void i71() { ADC(IndirectYAddr); pc++; }
- void i75() { ADC(ZeroPageXAddr); pc++; }
- void i76() { ROR(ZeroPageXAddr); pc++; }
- void i78() { SET(INT); }
- void i79() { ADC(AbsoluteYAddr); pc+=2; }
- void i7d() { ADC(AbsoluteXAddr); pc+=2; }
- void i7e() { ROR(AbsoluteXAddr); pc+=2; }
- void i81() { STA(IndirectXAddr); pc++; }
- void i84() { STY(ZeroPageAddr); pc++; }
- void i85() { STA(ZeroPageAddr); pc++; }
- void i86() { STX(ZeroPageAddr); pc++; }
- void i88() { y--; FlagsNZ(y); }
- void i8a() { a=x; FlagsNZ(a); }
- void i8c() { STY(AbsoluteAddr); pc+=2; }
- void i8d() { STA(AbsoluteAddr); pc+=2; }
- void i8e() { STX(AbsoluteAddr); pc+=2; }
- void i90() { BCL(CAR); }
- void i91() { STA(IndirectYAddr); pc++; }
- void i94() { STY(ZeroPageXAddr); pc++; }
- void i95() { STA(ZeroPageXAddr); pc++; }
- void i96() { STX(ZeroPageYAddr); pc++; }
- void i98() { a=y; FlagsNZ(a); }
- void i99() { STA(AbsoluteYAddr); pc+=2; }
- void i9a() { sp=x; }
- void i9d() { STA(AbsoluteXAddr); pc+=2; }
- void ia0() { y=ImmediateByte(); FlagsNZ(y); pc++; }
- void ia1() { LDA(IndirectXAddr); pc++; }
- void ia2() { x=ImmediateByte(); FlagsNZ(x); pc++; }
- void ia4() { LDY(ZeroPageAddr); pc++; }
- void ia5() { LDA(ZeroPageAddr); pc++; }
- void ia6() { LDX(ZeroPageAddr); pc++; }
- void ia8() { y=a; FlagsNZ(y); }
- void ia9() { a=ImmediateByte(); FlagsNZ(a); pc++; }
- void iaa() { x=a; FlagsNZ(x); }
- void iac() { LDY(AbsoluteAddr); pc+=2; }
- void iad() { LDA(AbsoluteAddr); pc+=2; }
- void iae() { LDX(AbsoluteAddr); pc+=2; }
- void ib0() { BST(CAR); }
- void ib1() { LDA(IndirectYAddr); pc++; }
- void ib4() { LDY(ZeroPageXAddr); pc++; }
- void ib5() { LDA(ZeroPageXAddr); pc++; }
- void ib6() { LDX(ZeroPageYAddr); pc++; }
- void ib8() { CLR(OVF); }
- void ib9() { LDA(AbsoluteYAddr); pc+=2; }
- void iba() { x=sp; }
- void ibc() { LDY(AbsoluteXAddr); pc+=2; }
- void ibd() { LDA(AbsoluteXAddr); pc+=2; }
- void ibe() { LDX(AbsoluteYAddr); pc+=2; }
- void ic0() {
- register byte tbyte;
- tbyte=ImmediateByte();
- flags &=~(CAR+ZER+NEG);
- if (y==tbyte) flags |=CAR+ZER;
- else if (y>tbyte) flags |=CAR;
- else flags |=NEG;
- pc++;
- }
- void ic1() { CMP(IndirectXAddr); pc++; }
- void ic4() { CPY(ZeroPageAddr); pc++; }
- void ic5() { CMP(ZeroPageAddr); pc++; }
- void ic6() { DECR(ZeroPageAddr); pc++; }
- void ic8() { y++; FlagsNZ(y); }
- void ic9() {
- register byte tbyte;
- tbyte=ImmediateByte();
- flags &=~(CAR+ZER+NEG);
- if (a==tbyte) flags |=CAR+ZER;
- else if (a>tbyte) flags |=CAR;
- else flags |=NEG;
- pc++;
- }
- void ica() { x--; FlagsNZ(x); }
- void icc() { CPY(AbsoluteAddr); pc+=2; }
- void icd() { CMP(AbsoluteAddr); pc+=2; }
- void ice() { DECR(AbsoluteAddr); pc+=2; }
- void id0() { BCL(ZER); }
- void id1() { CMP(IndirectYAddr); pc++; }
- void id5() { CMP(ZeroPageXAddr); pc++; }
- void id6() { DECR(ZeroPageXAddr); pc++; }
- void id8() { CLR(DEC); }
- void id9() { CMP(AbsoluteYAddr); pc+=2; }
- void idd() { CMP(AbsoluteXAddr); pc+=2; }
- void ide() { DECR(AbsoluteXAddr); pc+=2; }
- void ie0() {
- register byte tbyte;
- tbyte=ImmediateByte();
- flags &=~(CAR+ZER+NEG);
- if (x==tbyte) flags |=CAR+ZER;
- else if (x>tbyte) flags |=CAR;
- else flags |=NEG;
- pc++;
- }
- void ie1() { SBC(IndirectXAddr); pc++; }
- void ie4() { CPX(ZeroPageAddr); pc++; }
- void ie5() { SBC(ZeroPageAddr); pc++; }
- void ie6() { INCR(ZeroPageAddr); pc++; }
- void ie8() { x++; FlagsNZ(x); }
- void ie9() {
- register int data;
- data=ImmediateByte();
- if (flags&DEC) {
- data = bcd2dec[a]-bcd2dec[data]-((flags&CAR)?0:1);
- flags &= ~(CAR+ZER+NEG+OVF);
- if (data==0) flags |=ZER+CAR;
- else if (data>0) flags |=CAR;
- else {
- flags|=NEG;
- data +=100; }
- a=dec2bcd[data]; }
- else {
- data = a-data-((flags&CAR)?0:1);
- flags &=~(CAR+ZER+OVF+NEG);
- if (data==0) flags |= ZER+CAR;
- else if (data>0) flags |= CAR;
- else flags|=OVF;
- data &= 255;
- flags |= data&128;
- a=data; }
- pc++;
- }
- void iea() {}
- void iec() { CPX(AbsoluteAddr); pc+=2; }
- void ied() { SBC(AbsoluteAddr); pc+=2; }
- void iee() { INCR(AbsoluteAddr); pc+=2; }
- void if0() { BST(ZER); }
- void if1() { SBC(IndirectYAddr); pc++; }
- void if5() { SBC(ZeroPageXAddr); pc++; }
- void if6() { INCR(ZeroPageXAddr); pc++; }
- void if8() { SET(DEC); }
- void if9() { SBC(AbsoluteYAddr); pc+=2; }
- void ifd() { SBC(AbsoluteXAddr); pc+=2; }
- void ife() { INCR(AbsoluteXAddr); pc+=2; }
- void iff() { TrapExecute(); }
-
- void ini()
- {
- #ifdef MACSBUG
- DebugStr("\pNonImplemented!");
- #endif
- pc++;
- }
-
- int InstructionInitialize()
- {
- return kNoError;
- }
-
- void (* instruct[256]) () = {
- i00, i01, ini, ini, ini, i05, i06, ini,
- i08, i09, i0a, ini, ini, i0d, i0e, ini,
- i10, i11, ini, ini, ini, i15, i16, ini,
- i18, i19, ini, ini, ini, i1d, i1e, ini,
- i20, i21, ini, ini, i24, i25, i26, ini,
- i28, i29, i2a, ini, i2c, i2d, i2e, ini,
- i30, i31, ini, ini, ini, i35, i36, ini,
- i38, i39, ini, ini, ini, i3d, i3e, ini,
- i40, i41, ini, ini, ini, i45, i46, ini,
- i48, i49, i4a, ini, i4c, i4d, i4e, ini,
- i50, i51, ini, ini, ini, i55, i56, ini,
- i58, i59, ini, ini, ini, i5d, i5e, ini,
- i60, i61, ini, ini, ini, i65, i66, ini,
- i68, i69, i6a, ini, i6c, i6d, i6e, ini,
- i70, i71, ini, ini, ini, i75, i76, ini,
- i78, i79, ini, ini, ini, i7d, i7e, ini,
- ini, i81, ini, ini, i84, i85, i86, ini,
- i88, ini, i8a, ini, i8c, i8d, i8e, ini,
- i90, i91, ini, ini, i94, i95, i96, ini,
- i98, i99, i9a, ini, ini, i9d, ini, ini,
- ia0, ia1, ia2, ini, ia4, ia5, ia6, ini,
- ia8, ia9, iaa, ini, iac, iad, iae, ini,
- ib0, ib1, ini, ini, ib4, ib5, ib6, ini,
- ib8, ib9, iba, ini, ibc, ibd, ibe, ini,
- ic0, ic1, ini, ini, ic4, ic5, ic6, ini,
- ic8, ic9, ica, ini, icc, icd, ice, ini,
- id0, id1, ini, ini, ini, id5, id6, ini,
- id8, id9, ini, ini, ini, idd, ide, ini,
- ie0, ie1, ini, ini, ie4, ie5, ie6, ini,
- ie8, ie9, iea, ini, iec, ied, iee, ini,
- if0, if1, ini, ini, ini, if5, if6, ini,
- if8, if9, ini, ini, ini, ifd, ife, iff};
-
- byte cycletime[256]={
- /*00*/ 7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0,
- /*10*/ 3, 5, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
- /*20*/ 6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0,
- /*30*/ 3, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
- /*40*/ 6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0,
- /*50*/ 3, 6, 0, 0, 0, 3, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
- /*60*/ 6, 6, 0, 0, 0, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0,
- /*70*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
- /*80*/ 0, 6, 0, 0, 6, 3, 3, 0, 2, 0, 2, 0, 4, 4, 4, 0,
- /*90*/ 2, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 0, 5, 0, 0,
- /*A0*/ 2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0,
- /*B0*/ 3, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 5, 5, 5, 0,
- /*C0*/ 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
- /*D0*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
- /*E0*/ 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
- /*F0*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 1 };
-
-